#ifndef _KRLMEMPOOL_T_H_
#define _KRLMEMPOOL_T_H_

#include <hyper_t.h>
#include <spinlock_t.h>

#define KMEMP_BYTE_ALIGN(x)    ALIGN (x, 4)
#define KMEMP_ONEPAGE_SZ       0x1000                   /* 页级内存池中的一个页大小 */
#define KMEMP_ONEBYTEPOOL_SZ   0x4000                   /* 一个字节级内存池空间大小 */

#define KMEMP_ALCSZ_MIN        1
#define KMEMP_ALCSZ_MAX        0x4000000                /* 4MB */

#define KMEMP_BYTE_OR_PAGE_SZ  2048                     /* 字节级 页级内存管理门槛值 */
#define KMEMP_HAL_BLK_SZ       (KMEMP_ONEPAGE_SZ * 31)  /* 最大分配页面字节数 */

/* mempoolhead_t 类型 */

#define KMEMP_HDTYPE_NA        0        /* 未知 */
#define KMEMP_HDTYPE_PAGE      1        /* 页级 */
#define KMEMP_HDTYPE_BYTE      2        /* 字节级 */

/* 内存池页状态描述数据结构 */

typedef struct s_MEMPAGEDSC 
    {
    addr_t                addrstart; /* 保存内存池中的一个页面的首地址 */
    struct s_MEMPAGEDSC * next;      /* 指向自己的指针 */
    } mempagedsc_t;

/* 内存池管理头 */

typedef struct s_MEMPOOLHEAD 
    {
    spinlock_t     lock;                /* 保护自身的自旋锁 */
    list_t         list;                /* 链表 */
    uint_t         type;                /* 区分 页级还是字节级内存池 */
    addr_t         addrstart;           /* 内存池开始地址 */
    addr_t         addrend;             /* 内存池结束地址 */
    mempagedsc_t * firstfreepagedsc;    /* 第一个空闲页状态描述结构体 */    
    addr_t         firstfreeobjaddr;    /* 第一个空闲对象的起始地址 */
    uint_t         objtotnbr;           /* 内存池中对象 (字节空间/页) 的个数 */
    uint_t         objsz;               /* 内存池中对象(字节空间/页) 的大小 */    
    uint_t         objactlsz;           /* 内存池中对象 (字节空间/页) 的实际大小 */
    uint_t         objallocednbr;       /* 已分配对象(字节空间/页) 的个数 */
    uint_t         nextobjofst;         /* 下一个对象 (字节空间) 指针的偏移 */

    /* mempagedsc 必须作为 mempoolhead_t 结构体的结束成员 */

    uint_t         mempagedscnbr;       /* 页状态描述结构的个数 */
    mempagedsc_t * mempagedsc;          /* 页状态描述结构的存放地址 */
    } mempoolhead_t;

/* 内存池容器 */

typedef struct s_KMEMPOOL
    {
    spinlock_t      lock;                /* 保护自身的自旋锁 */
    list_t          list;                /* 链表 */
    uint_t          status;              /* 状态 */
    uint_t          flags;               /* 标志 */
    spinlock_t      pagelock;            /* 保护页级内存池的自旋锁 */
    spinlock_t      bytelock;            /* 保护字节级别 */
    uint_t          pagepoolnbr;         /* 页级内存池个数 */
    uint_t          bytepoolnbr;         /* 字节级内存池个数 */    
    list_t          pagepoolheadlst;     /* 页级内存池的链表头 */
    list_t          bytepoolheadlst;     /* 字节级内存池链表头 */
    mempoolhead_t * lastoppagepool;      /* 保存上次操作过的页级 mempoolhead_t 结构体 */
    mempoolhead_t * lastopbytepool;      /* 保存上次操作过的字节级 mempoolhead_t 结构体 */
    } kmempool_t;

#endif
